//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package ciicos.controller;

import ciicos.base.ActionResult;
import ciicos.base.NoDataSourceBind;
import ciicos.base.UserInfo;
import ciicos.base.service.SysconfigService;
import ciicos.config.ConfigValueUtil;
import ciicos.config.JnpfOauthConfig;
import ciicos.consts.DeviceType;
import ciicos.consts.LoginTicketStatus;
import ciicos.exception.LoginException;
import ciicos.granter.TokenGranterBuilder;
import ciicos.model.BaseSystemInfo;
import ciicos.model.LoginConfigModel;
import ciicos.model.LoginModel;
import ciicos.model.LoginTicketModel;
import ciicos.model.login.LoginForm;
import ciicos.model.login.LoginVO;
import ciicos.model.login.PcUserVO;
import ciicos.permission.controller.SocialsUserController;
import ciicos.permission.entity.UserEntity;
import ciicos.permission.model.socails.SocialsUserVo;
import ciicos.permission.service.UserService;
import ciicos.service.AuthService;
import ciicos.service.LoginService;
import ciicos.util.DownUtil;
import ciicos.util.Md5Util;
import ciicos.util.RedisUtil;
import ciicos.util.ServletUtil;
import ciicos.util.StringUtil;
import ciicos.util.TicketUtil;
import ciicos.util.UserProvider;
import ciicos.util.data.DataSourceContextHolder;
import cn.hutool.core.collection.CollectionUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Api(
        tags = {"登陆数据"},
        value = "oauth"
)
@RestController
@RequestMapping({"/api/oauth"})
public class LoginController {
    @Autowired
    private UserService userApi;
    @Autowired
    private LoginService loginService;
    @Autowired
    private AuthService authService;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private JnpfOauthConfig oauthConfig;
    @Autowired
    private SysconfigService sysConfigApi;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private TokenGranterBuilder tokenGranterBuilder;
    @Autowired
    private SocialsUserController socialsUserApi;

    @ApiOperation("登陆")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "parameters",
            value = "登录参数",
            required = true
    )})
    @RequestMapping(
            value = {"/Login/**"},
            method = {RequestMethod.GET, RequestMethod.POST}
    )
    public ActionResult<LoginVO> login(@RequestParam Map<String, String> parameters) throws LoginException {
        return this.authService.login(parameters);
    }

    @ApiOperation("锁屏解锁登录")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "loginForm",
            value = "登录模型",
            required = true
    )})
    @PostMapping({"/LockScreen"})
    public ActionResult lockScreen(@RequestBody LoginForm loginForm) throws LoginException {
        UserEntity userEntity = this.userApi.getUserByAccount(loginForm.getAccount());
        if (userEntity == null) {
            UserInfo userInfo = UserProvider.getUser();
            if (userInfo.getUserId() != null) {
                UserProvider.logoutByUserId(userInfo.getUserId());
            }

            throw new LoginException("账号不存在");
        } else if (!Md5Util.getStringMd5(loginForm.getPassword().toLowerCase() + userEntity.getSecretkey().toLowerCase()).equals(userEntity.getPassword())) {
            throw new LoginException("账户或密码错误，请重新输入。");
        } else {
            return ActionResult.success("验证成功");
        }
    }

    @NoDataSourceBind
    @ApiOperation("退出")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "grandtype",
            value = "登录类型",
            required = true
    )})
    @RequestMapping(
            value = {"/Logout", "/Logout/{grandtype}"},
            method = {RequestMethod.GET, RequestMethod.POST}
    )
    public ActionResult logout(@PathVariable(value = "grandtype",required = false) String grandtype) {
        return this.tokenGranterBuilder.getGranterByLogin(grandtype).logout();
    }

    @NoDataSourceBind
    @ApiOperation("踢出指定用户")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "tokens",
            value = "token集合"
    ), @ApiImplicitParam(
            name = "userId",
            value = "租户id"
    ), @ApiImplicitParam(
            name = "tenantId",
            value = "租户id"
    )})
    @PostMapping({"/KickoutToken"})
    public void kickoutByToken(@RequestParam(value = "tokens",required = false) String[] tokens, @RequestParam(name = "userId",required = false) String userId, @RequestParam(name = "tenantId",required = false) String tenantId) {
        if (StringUtil.isNotEmpty(tokens)) {
            this.authService.kickoutByToken(tokens);
        } else {
            this.authService.kickoutByUserId(userId, tenantId);
        }

    }

    @ApiOperation("获取用户登录信息")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "type",
            value = "Web/App"
    )})
    @GetMapping({"/CurrentUser"})
    public ActionResult<PcUserVO> currentUser(String type) throws LoginException {
        if (StringUtil.isEmpty(type)) {
            type = "Web";
        } else {
            type = "App";
        }

        UserInfo userInfo = UserProvider.getUser();
        if (DeviceType.TEMPUSERLIMITED.getDevice().equals(userInfo.getLoginDevice())) {
            throw new LoginException("限制会话, 不允许访问系统");
        } else {
            PcUserVO pcUserVO = this.loginService.getCurrentUser(type);
            if (pcUserVO == null) {
                throw new LoginException("账户异常");
            } else {
                return ActionResult.success(pcUserVO);
            }
        }
    }

    @ApiOperation("修改密码信息发送")
    @PostMapping({"/updatePasswordMessage"})
    public ActionResult updatePasswordMessage() {
        this.loginService.updatePasswordMessage();
        return ActionResult.success();
    }

    @NoDataSourceBind
    @ApiOperation("图形验证码")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "codeLength",
            value = "验证码长度",
            required = true
    ), @ApiImplicitParam(
            name = "timestamp",
            value = "验证码标识",
            required = true
    )})
    @GetMapping({"/ImageCode/{codeLength}/{timestamp}"})
    public void imageCode(@PathVariable("codeLength") Integer codeLength, @PathVariable("timestamp") String timestamp) {
        DownUtil.downCode(codeLength);
        this.redisUtil.insert(timestamp, ServletUtil.getSession().getAttribute("RANDOMCODEKEY"), 300L);
    }

    @ApiOperation("注销用户")
    @PostMapping({"/logoutCurrentUser"})
    public ActionResult logoutCurrentUser() {
        UserInfo userInfo = UserProvider.getUser();
        if (userInfo.getIsAdministrator() != null && UserProvider.getUser().getIsAdministrator()) {
            return ActionResult.fail("管理员不能注销");
        } else {
            if (userInfo.getIsAdministrator() != null && !userInfo.getIsAdministrator()) {
                this.userApi.delete(this.userApi.getInfo(userInfo.getUserId()));
                UserProvider.kickoutByUserId(userInfo.getUserId(), DataSourceContextHolder.getDatasourceId());
            }

            return ActionResult.success("注销成功");
        }
    }

    @NoDataSourceBind
    @ApiOperation("判断是否需要验证码")
    @ApiImplicitParams({@ApiImplicitParam(
            name = "account",
            value = "账号",
            required = true
    )})
    @GetMapping({"/getConfig/{account}"})
    public ActionResult<LoginModel> check(@PathVariable("account") String account) throws LoginException {
        LoginModel loginModel = new LoginModel();
        String tenantId = "0";
        String tenantDbConnectionString = "0";
        if (this.configValueUtil.isMultiTenancy()) {
            LoginForm loginForm = new LoginForm();
            loginForm.setAccount(account);
            UserInfo userInfo = new UserInfo();
            userInfo.setUserAccount(loginForm.getAccount());
            userInfo = this.loginService.getTenantAccount(userInfo);
            tenantId = userInfo.getTenantId();
            tenantDbConnectionString = userInfo.getTenantDbConnectionString();
        }

        BaseSystemInfo sysConfigInfo = this.sysConfigApi.getSysInfo();
        if (Objects.nonNull(sysConfigInfo) && "1".equals(String.valueOf(sysConfigInfo.getEnableVerificationCode()))) {
            loginModel.setEnableVerificationCode(1);
            Integer verificationCodeNumber = sysConfigInfo.getVerificationCodeNumber();
            loginModel.setVerificationCodeNumber(verificationCodeNumber == null ? 4 : verificationCodeNumber);
            return ActionResult.success(loginModel);
        } else {
            loginModel.setEnableVerificationCode(0);
            return ActionResult.success(loginModel);
        }
    }

    @NoDataSourceBind
    @ApiOperation("获取登录配置")
    @GetMapping({"/getLoginConfig"})
    public ActionResult<LoginConfigModel> getLoginConfig() {
        LoginConfigModel loginConfigModel = new LoginConfigModel();
        if (this.oauthConfig.getSsoEnabled()) {
            String url = this.oauthConfig.getLoginPath() + "/" + this.oauthConfig.getDefaultSSO();
            loginConfigModel.setRedirect(true);
            loginConfigModel.setUrl(url);
            loginConfigModel.setTicketParams("jnpf_ticket");
        } else {
            List<SocialsUserVo> loginList = this.socialsUserApi.getLoginList("jnpf_ticket".toUpperCase());
            if (CollectionUtil.isNotEmpty(loginList)) {
                loginConfigModel.setSocialsList(loginList);
                loginConfigModel.setRedirect(false);
                loginConfigModel.setTicketParams("jnpf_ticket");
            }
        }

        return ActionResult.success(loginConfigModel);
    }

    @NoDataSourceBind
    @ApiOperation("获取登录票据")
    @GetMapping({"/getTicket"})
    public ActionResult<String> getTicket() {
        LoginTicketModel ticketModel = new LoginTicketModel();
        ticketModel.setTicketTimeout(System.currentTimeMillis() + this.oauthConfig.getTicketTimeout() * 1000L);
        String ticket = TicketUtil.createTicket(ticketModel, this.oauthConfig.getTicketTimeout());
        return ActionResult.success(ticketModel.getTicketTimeout().toString(), ticket);
    }

    @NoDataSourceBind
    @ApiOperation("获取登录状态")
    @GetMapping({"/getTicketStatus/{ticket}"})
    public ActionResult<LoginTicketModel> getTicketStatus(@PathVariable("ticket") String ticket) {
        LoginTicketModel ticketModel = (LoginTicketModel)TicketUtil.parseTicket(ticket);
        if (ticketModel == null) {
            ticketModel = (new LoginTicketModel()).setStatus(LoginTicketStatus.Invalid.getStatus()).setValue("票据失效！");
        } else if (ticketModel.getStatus() != LoginTicketStatus.UnLogin.getStatus() && ticketModel.getStatus() != LoginTicketStatus.UnBind.getStatus()) {
            TicketUtil.deleteTicket(ticket);
        }

        return ActionResult.success(ticketModel);
    }
}
